/**
 *扑克类
 * <b>功能描述</b>
 *  <ul>
 *  <li>七张牌中选出五张最大的组合和牌型；</li>
 *  <li>多人之间比牌，排列出名次；</li>
 *  </ul>
 *  <b>運行環境</b>
 *  <ul>
 *    <li>SFS</li>
 *    <li>继承 poker 类</li>
 *  </ul>
 * @package as3Example
 * @filesource
 */

function texasPoker()
{
	poker.call(this);
	this._my_max_cards = Array();
	this._rule = Array(
						'FLUSH_WAY', 		// 同花顺
						'FOUR_OF_A_KIND',	// 四条
						'FULL_HOUSE', 		// 三条加一对
						'FLUSH', 			// 同花
						'WAY', 				// 顺子
						'THREE_OF_A_KIND',  // 三条
						'TWO_TWAIN', 		// 两对
						'TWAIN',			// 一对
						'OFFSUIT'			// 杂牌
					);
}
	texasPoker.prototype = poker.prototype; //继承父类poker的方法
	/**
	* 获取最大牌型和牌的组合
	* <b>作用：</b>
	* 七张牌中选出五张最大的组合和牌型；
	* {@source }  
	* @access public
	* @param array r_private_cards 2 张自己的牌
	* @param array r_public_cards 5 张公共牌
	* @return boolean | array 参数错误时返回 false，否则返回 array(
	* 																'cards'   // 五张最大的牌型组合
	*																'result'  // 牌型结果
	* 															   )
	*/

	texasPoker.prototype.getResult = function(r_private_cards, r_public_cards)
	{
		
		if ( (r_private_cards== undefined) || (r_private_cards.length != 2) || (r_public_cards.length != 5 ))
			{
				return false;
			}
		var _cards = r_private_cards.concat(r_public_cards);
		var _analyse_result = this._analyse(_cards);		
		var _my_max_cards = this._getMyMaxCards(_analyse_result);
		return _my_max_cards;
	}

	/**
	* 分析
	* <b>作用：</b>
	* 对持有牌进行分析，并返回分析结果
	* {@source }  
	* @access private
	* @param array r_cards 要分析的牌
	* @return array array 分析结果：card:排序后的牌面、amount:2个及以上的数量、suit:花色数量、way:顺序结构、possibility:预估结果
	*/
	texasPoker.prototype._analyse = function(r_cards)
	{
		var _cards = this.sort(r_cards, 'DESC');
		var _result = new Object();
		_result['source'] 		 = _cards;
		_result['a2345'] 		 = { 'spade':Array(), 'heart':Array(), 'club':Array(), 'diamond':Array(), 'way':Array() };
		_result['flushWay'] 	 = { 'spade':Array(), 'heart':Array(), 'club':Array(), 'diamond':Array() };
		_result['fourOfAKind'] 	 = Array();
		_result['fullHouse'] 	 = Array();
		_result['flush'] 		 = { 'spade':Array(), 'heart':Array(), 'club':Array(), 'diamond':Array() };
		_result['way'] 		     = Array();
		_result['threeOfAKind']  = Array();
		_result['twoTwain'] 	 = Array();
		_result['twain'] 		 = Array();
		_result['offsuit']  	 = Array();
		var _amount = Array();
		var _way = Array();
		var _flush_way = {'spade':Array(), 'heart':Array(), 'club':Array(), 'diamond':Array() };
		var _i = 0;
		var _up_card ;
		var _label;
		var _value;
		var _suit ;
		for each(var _card in _result['source'])
		{
			_label = _card['label'];
			_value = _card['value'];
			_suit  = String(_card['suit']).toLocaleLowerCase();					
			_result['flush'][_suit].push(_card);
			var _tmp_amount =_amount[_value] == undefined ? 0: Number(_amount[_value]);
			_amount[_value] = _tmp_amount+1;
	
			if (1 == _amount[_value]) {
				_result['offsuit'].push(_card); 
			}else if (2 == _amount[_value]) {
				_up_card = _result['offsuit'].pop(); 
				_result['twain'].push(_up_card);
				_result['twain'].push(_card);
			}else if (3 == _amount[_value]) {
				_up_card = _result['twain'].splice( -2);
				_result['threeOfAKind'] = _result['threeOfAKind'].concat(_up_card);
				_result['threeOfAKind'].push(_card);
			}else if (4 == _amount[_value]) {
				_up_card = _result['threeOfAKind'].splice( -3);
				_result['fourOfAKind'] = _result['fourOfAKind'].concat(_up_card);
				_result['fourOfAKind'].push(_card);				
			}
			//判斷A 2 3 4 5
			if (14 == _value || (_value >= 2 && _value <= 5)) {
				_result['a2345'][_suit].push(_card);
				_result['a2345']['way'][_value] = _card;
			}
			//順子
			if ( 0 == _result['way'].length) {
				_result['way'].push(_card);
			}else if (_way['value'] - _value == 1) {
				_result['way'].push(_card);
			}else if (_way['value'] != _value) {				
				if (_result['way'].length < 5) {
					_result['way'] = Array();  
				}
				if (_i <= 2) {  //清空的牌數沒有超過3張,剩余的牌還有可能組成順子
					_result['way'].push(_card);
				}
			}
			//同花順
			if (0 == _flush_way[_suit].length) {
				_result['flushWay'][_suit].push(_card);
			}else if (_flush_way[_suit]['value'] - _value == 1) {
				_result['flushWay'][_suit].push(_card);
			}else {
				if (_result['flushWay'][_flush_way[_suit]['suit'].toLocaleLowerCase()].length < 5) {
					_result['flushWay'][_flush_way[_suit]['suit'].toLocaleLowerCase()].pop();
				}
				if(_i <= 2){
					_result['flushWay'][_suit].push(_card);
				}
			}
			_way = _card;
			_flush_way[_suit] = _card;
			_i++;			
		}	
		//处理三条加一对
		var _three_count = _result['threeOfAKind'].length;
		var _twain_count  = _result['twain'].length;
		if (_three_count > 0) {
			if (6 == _three_count) {
				var tmp_arr = _result['threeOfAKind'].splice(0, 5);
				_result['fullHouse'] = _result['fullHouse'].concat(tmp_arr); 
			}else if (_twain_count > 0) {
				_result['fullHouse'] = _result['threeOfAKind'];
				_result['fullHouse'] = _result['fullHouse'].concat(_result['twain'].splice(0, 2));
			}
			
		}
		// 处理两对
		if (_three_count == 0 && _twain_count >= 4 ) {
			_result['twoTwain'] = _result['twoTwain'].concat(_result['twain'].splice(0, 4));
		}		
		return _result;				
	}
	/**
	* 七张牌中获取最大牌及牌型
	* {@source }  
	* @access private
	* @param array r_analyse_result 分析结果
	* @return  array array array(
	* 								'cards'   // 五张最大的牌型组合
	*								'result'  // 牌型结果
	* 							 )
	*/
	texasPoker.prototype._getMyMaxCards = function(r_analyse_result) {
		var _my_max = { };
		_my_max['cards'] = Array();
		_my_max['result'] = '';
		//同花順
		for (var _key in r_analyse_result['flushWay']) {
			if (r_analyse_result['flushWay'][_key].length >= 5) {
				_my_max['cards'] = r_analyse_result['flushWay'][_key].splice(0, 5);
				_my_max['result'] = 'FLUSH_WAY';
				return _my_max;
			}
		}
		//A2345同花順
		for each(var _key in r_analyse_result['a2345']) {
			if ('way' == _key) continue;
			if (r_analyse_result['a2345'].length >= 5) {
				_my_max['cards'] = r_analyse_result['a2345'].splice(0, 5);
				_my_max['result'] = 'FLUSH_WAY';
				return _my_max;
			}
		}
		//四條
		if ( 4 == r_analyse_result['fourOfAKind']) {
			_my_max['cards'] = r_analyse_result['fourOfAKind'];
			this.set(r_analyse_result['source']);
			this.remove(_my_max['cards']);
			var _cards = this.get();
			_my_max['cards'].concat(_cards[0]);
			_my_max['result'] = 'FOUR_OF_A_KIND';
			return _my_max;			
		}
		//三條加一對
	
		if ( 5 == r_analyse_result['fullHouse'].length) {
			_my_max['cards'] = r_analyse_result['fullHouse'];
			_my_max['result'] = 'FULL_HOUSE';
			return _my_max;
		}
		//同花
		for ( var _key in r_analyse_result['flush']) {
			if (r_analyse_result['flush'][_key].length >= 5) {
				_my_max['cards'] = r_analyse_result['flush'][_key].splice(0, 5);
				_my_max['result'] = 'FLUSH';
				return _my_max;
			}
		}
		//順子			
		if (r_analyse_result['way'].length >= 5 ) {
			_my_max['cards'] = r_analyse_result['way'].splice(0, 5);
			_my_max['result'] = 'WAY';			
			return _my_max;
		}
		//A2345 順子
		var _way_count = 0;
		var _way_cards = Array();
		for each(var _val in r_analyse_result['a2345']['way']) {
			_way_count++;
			_way_cards.push(_val);
		}
		if (5 == _way_count) {
			_my_max['cards'] = _way_cards.splice(0, 5);
			_my_max['result'] = 'WAY';
			return _my_max;
		}
		//三條
		_count = r_analyse_result['threeOfAKind'].length;
		if (_count > 0) {
			_my_max['cards'] = _my_max['cards'].concat(r_analyse_result['threeOfAKind']);
			_my_max['cards'] = _my_max['cards'].concat(r_analyse_result['offsuit'].splice(0, 2));
			_my_max['result'] = 'THREE_OF_A_KIND';
			return _my_max;
		}
		//兩對

		if (4 == r_analyse_result['twoTwain'].length) {
			_my_max['cards'] = r_analyse_result['twoTwain'];
			this.set(r_analyse_result['source']);
			this.remove(_my_max['cards']);
			var _cards = this.get();
			_my_max['cards'] = _my_max['cards'].concat(_cards[0]);
			_my_max['result'] = 'TWO_TWAIN';
			return _my_max;
		}
		//一對		
		if (2 == r_analyse_result['twain'].length) {
			_my_max['cards'] = r_analyse_result['twain'];
			var _other_cards = r_analyse_result['offsuit'].splice(0, 3);
			_my_max['cards'] = _my_max['cards'].concat(_other_cards);
			_my_max['result'] = 'TWAIN';
			return _my_max;
		}
		_my_max['cards'] = r_analyse_result['offsuit'].splice(0, 5);
		_my_max['result'] = 'OFFSUIT';
		return _my_max;
	}
	/**
	* 比较多副牌的大小
	* {@source }  
	* @access public
	* @param array r_cards 要比较的牌，key 为牌持有者的编号
	* @return array array 返回结果 array('持牌者编号1','持牌者编号2'......) key = 0 为胜者，如果 key = 0 为 array，说明 array 内的持牌者编号牌一样大
	*/
	texasPoker.prototype.compare = function(r_cards) {
		var _rule = { };
		var _count = 0;
		for( var _key in this._rule) {
			_count++
			_rule[this._rule[_key]] = _key;		
		}
		var _analyse = Array();
		var _val;
		var _card_value;
		var _card_rule;
		for (var _key in r_cards) {
			_val = r_cards[_key];
			_sum_value = _val['cards'][0]['value'] + _val['cards'][1]['value'] + _val['cards'][2]['value'] + _val['cards'][3]['value'] + _val['cards'][4]['value'];
			if (_rule[_val['result']] != null) {
				_card_rule = _count -_rule[_val['result']];
			}else {
				return false;
			}			
			 _card_value = _card_rule * 100 + _sum_value;
			_analyse.push( { value:_card_value, key:_key } );
			//_analyse.push( { value:_card_value, key:_val['key'] } );
		}		
		_analyse.sort(_descSort);
		var _i = 0;
		var _up_result = 0;		
		var _result = Array();
		for each(var _val in _analyse) {
			var _tmp_array = Array();			
			if (0 == _up_result) {
				_up_result = _val['value'];
			}else if (_up_result > _val['value']) {
				_i++;
			}
			/**
			这里用于比较不是最大牌中的相同牌
			if (_up_result > _val['value']) {
				_i++;
			}
			_up_result = _val['value'];			
			 */
			if (_result[_i]) {
				if (typeof(_result[_i]) == 'object') {
					_result[_i].push(_val['key']);
				}else {
					_tmp_array.push(_result[_i]);
					_tmp_array.push(_val['key']);				
					_result[_i] = _tmp_array;
				}
			}else {
				_result[_i] = _val['key'];
			}
		}
		return _result;
	}
	
	function _descSort(r_a_element, r_b_element)
	{
		if (r_a_element['value'] <= r_b_element['value']) {
			return 1;
		}else if(r_a_element['value'] > r_b_element['value']){
			return -1;
		}
	}
		
	
	
	
	
	
	
	
	
	
	
	
	
